Skip to content

fix(security): escape customData fields in option aria-label (XSS bypass)#470

Closed
gnbm wants to merge 1 commit into
masterfrom
security/escape-customdata-attributes
Closed

fix(security): escape customData fields in option aria-label (XSS bypass)#470
gnbm wants to merge 1 commit into
masterfrom
security/escape-customdata-attributes

Conversation

@gnbm

@gnbm gnbm commented Jun 3, 2026

Copy link
Copy Markdown
Collaborator

Problem

customData.group_name and customData.description are interpolated straight into the option aria-label attribute in renderOptions() without escaping:

groupName = d.customData.group_name !== undefined ? `${d.customData.group_name}, ` : '';
optionDesc = d.customData.description !== undefined ? ` ${d.customData.description},` : '';
ariaLabel = `aria-label="${groupName} ${d.label}, ${optionDesc}"`;

A " in either field breaks out of the attribute and can inject markup / event handlers — and this happens even when enableSecureText is enabled, since customData never went through secureText(). That makes it an XSS bypass for security-conscious consumers.

Fix

Route both customData fields through secureText() (the same escaping used for label/value). secureText() is a no-op when enableSecureText is disabled, so behaviour is unchanged for consumers that intentionally pass raw text.

Verification

New spec cypress/e2e/security-customdata-xss.cy.ts:

  • mounts a grouped dropdown with a breakout payload in customData (with enableSecureText: true) and asserts no <img> is injected and the onerror never runs;
  • asserts the aria-label stays intact (escaped, not broken out).

Other Validations:

  • Ran npm run validate for static code validation: image
  • npm run build: succeeds; dist/docs rebuilt
  • All tests passed (ran npm run test ):
image

customData.group_name and customData.description were interpolated directly into
the option aria-label attribute without escaping. A double quote in those fields
could break out of the attribute and inject markup/handlers even when
enableSecureText was enabled - an XSS bypass.

Route both fields through secureText() (same path as label/value). secureText is
a no-op when enableSecureText is disabled, so behaviour is unchanged for
consumers that intentionally pass raw text.

Adds cypress regression spec security-customdata-xss.cy.ts.
@gnbm

gnbm commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator Author

Closing as already resolved on master. The customData aria-label escaping fix here is present identically on current master (it routes group_name/description through secureText, which pre-escapes " via replaceDoubleQuotesWithHTML). This branch was cut from v1.2.0 and is now CONFLICTING; nothing remains to merge. Superseded by the merged hardening work (#468, #475#479). The only unmerged item across this stack — the enableSecureText warning + docs — has been rebased onto master in #480.

@gnbm gnbm closed this Jun 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant